#include "VSWorld.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
#include "VSResourceManager.h"
#include "VSStaticActor.h"
#include "VSSkelectonActor.h"
#include "VSGraphicInclude.h"
#include "VSSceneManager.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSWorld,VSObject)
BEGIN_ADD_PROPERTY(VSWorld,VSObject)
END_ADD_PROPERTY
IMPLEMENT_INITIAL_BEGIN(VSWorld)
IMPLEMENT_INITIAL_END
VSWorld * VSWorld::ms_pWorld = NULL;
VSWorld::VSWorld()
{
	ms_pWorld = this;
	VSSceneMap * pSceneMap = VS_NEW VSSceneMap("Main");
	m_SceneArray.AddElement(pSceneMap);
	
	//m_pMainCameraActor = VS_NEW VSCameraActor();
	//pSceneMap->AddActor(m_pMainCameraActor);
}
VSWorld::~VSWorld()
{
	//m_pMainCameraActor = NULL;
	m_SceneArray.Clear();
	VSMAC_ASSERT(m_ActorArray.GetNum() == 0);
}

VSSceneMap* VSWorld::CreateScene(const TCHAR * pName)
{
	for (unsigned int i = 0 ; i < m_SceneArray.GetNum() ;i++)
	{
		if(m_SceneArray[i]->m_Name == pName)
			return NULL;

	}
	VSSceneMap * pSceneMap = VS_NEW VSSceneMap(pName);
	m_SceneArray.AddElement(pSceneMap);
	return pSceneMap;
}
VSSceneMap * VSWorld::GetScene(const VSUsedName & Name)
{
	for (unsigned int i = 0 ; i < m_SceneArray.GetNum() ;i++)
	{
		if(m_SceneArray[i]->m_Name == Name)
			return m_SceneArray[i];

	}
	return NULL;
}
void VSWorld::Update(double dAppTime)
{
	static double LastTime = dAppTime;
	double DetTime = dAppTime - LastTime;
	LastTime = dAppTime;

	for (unsigned int i = 0 ; i < m_ActorArray.GetNum() ; i++)
	{
		m_ActorArray[i]->Update(dAppTime);
	}
	unsigned int i = 0 ;
	while(i < m_MessageArray.GetNum())
	{
		if (m_MessageArray[i].DispatchTime <= 0.0)
		{
			if (m_ActorArray[m_MessageArray[i].uiReceiver])
			{
				m_ActorArray[m_MessageArray[i].uiReceiver]->HandleMessage(m_MessageArray[i]);
			}
			m_MessageArray.Erase(i);
		}
		else
		{
			m_MessageArray[i].DispatchTime -= DetTime;
			i++;
		}
	}

}
VSActor *VSWorld::GetActor(VSUsedName Name)
{
	for (unsigned int i = 0 ; i < m_ActorArray.GetNum() ; i++)
	{
		if (m_ActorArray[i]->m_ActorName == Name)
		{

			return m_ActorArray[i];
		}
	}	
	return NULL;
}

void VSWorld::DeleteActor(VSActor * pActor)
{

	for (unsigned int i = 0 ; i < m_ActorArray.GetNum() ; i++)
	{
		if (m_ActorArray[i] == pActor)
		{
			m_ActorArray.Erase(i);
			return ;
		}
	}
}
void VSWorld::AddActor(VSActor * pActor)
{
	if (pActor)
	{
		m_ActorArray.AddElement(pActor);
	}
	
}
VSActor * VSWorld::CreateActor(const TCHAR *  ActorPath,VSSceneMap * pSceneMap)
{
	if (!ActorPath)
	{
		return NULL;
	}
	VSResourceProxyBase * pResouce = VSResourceManager::LoadResource(ActorPath,false);
	if (pResouce)
	{
		unsigned int ResourceType = pResouce->GetResourceType();
		if (ResourceType == VSResource::RT_STATIC_MESH)
		{
			VSStaticActor * pStateActor = VS_NEW VSStaticActor();
			pStateActor->m_pStaticMeshResource = (VSStaticMeshNodeR *)pResouce;
			pResouce->AddLoadEventObject(pStateActor);
			

			if (pSceneMap)
			{		
				pSceneMap->AddActor(pStateActor);
			}
			else
			{
				m_SceneArray[0]->AddActor(pStateActor);
			}

			return pStateActor;
		}
		else if (ResourceType == VSResource::RT_SKELECTON_MESH)
		{
			VSSkelectonActor * pSkelectonActor = VS_NEW VSSkelectonActor();
			pSkelectonActor->m_pSkelectonMeshResource = (VSSkelectonMeshNodeR *)pResouce;
			pResouce->AddLoadEventObject(pSkelectonActor);
			

			if (pSceneMap)
			{		
				pSceneMap->AddActor(pSkelectonActor);
			}
			else
			{
				m_SceneArray[0]->AddActor(pSkelectonActor);
			}

			return pSkelectonActor;
		}
		
	}
	return NULL;
}
void VSWorld::AddMessage(const VSMessage & Message)
{
	m_MessageArray.AddElement(Message);
}
void VSWorld::AttachCaptureViewFamilyToCamera(VSCameraActor * pCameraActor,
									 unsigned int uiCaptureViewFamilyType,const VSString & ViewFamilyName,
									 unsigned int uiWidth,unsigned int uiHeight,
									 VSArray<VSString> & SceneMapName,
									 VSPostEffectSetRPtr  pPostEffectSet,
									 bool bDrawDebugInfo,bool bBeforePostDebugDraw)
{
	VSCamera * pCamera = (VSCamera *)pCameraActor->GetActorNode();
	if (pCamera)
	{
		VSViewFamliyInfo * pInfo = VS_NEW VSViewFamliyInfo();
		
		VSViewFamily * pViewFamily = NULL;
		if (uiCaptureViewFamilyType == VSCaptureViewFamily::VT_CAPTURE_2D_CAPTURE_NORMAL)
		{
			pViewFamily = VS_NEW VSCaptureViewFamily(ViewFamilyName,uiWidth,uiHeight,pCamera,pPostEffectSet,bDrawDebugInfo,bBeforePostDebugDraw);

		}
		else if (uiCaptureViewFamilyType == VSCaptureViewFamily::VT_CAPTURE_CUB_CAPTURE_NORMAL)
		{
			pViewFamily = VS_NEW VS3DCaptureViewFamily(ViewFamilyName,uiWidth,uiHeight,pCamera,pPostEffectSet,bDrawDebugInfo,bBeforePostDebugDraw);
		}

		pInfo->m_SceneMapName = SceneMapName;
		pInfo->m_uiCaptureViewFamilyType = uiCaptureViewFamilyType;
		pInfo->m_uiHeight = uiHeight;
		pInfo->m_uiWidth = uiWidth;
		pInfo->m_pPostEffect = pPostEffectSet;
		pInfo->m_bBeforePostDebugDraw = bBeforePostDebugDraw;
		pInfo->m_bDrawDebugInfo = bDrawDebugInfo;
		pInfo->m_ViewFamilyName = ViewFamilyName;
		pInfo->m_pViewFamily = pViewFamily;
		pCameraActor->m_ViewFamliyInfoArray.AddElement(pInfo);
		pInfo->GetScene();
	}
}
void VSWorld::AttachWindowViewFamilyToCamera(VSCameraActor * pCameraActor,
									unsigned int uiWindowViewFamilyType,const VSString & ViewFamilyName,
									VSArray<VSString> & SceneMapName,
									int iWindowID,
									VSPostEffectSetRPtr pPostEffectSet,bool bDrawDebugInfo,bool bBeforePostDebugDraw)
{
	VSCamera * pCamera = (VSCamera *)pCameraActor->GetActorNode();
	if (pCamera)
	{
		VSViewFamliyInfo * pInfo = VS_NEW VSViewFamliyInfo();

		VSViewFamily * pViewFamily = NULL;
		if (uiWindowViewFamilyType == VSWindowViewFamily::VT_WINDOW_NORMAL)
		{
			pViewFamily= VS_NEW VSWindowViewFamily(ViewFamilyName,pCamera,pPostEffectSet,iWindowID,bDrawDebugInfo,bBeforePostDebugDraw);
			
			
		}
		pInfo->m_SceneMapName = SceneMapName;
		pInfo->m_uiCaptureViewFamilyType = uiWindowViewFamilyType;
		pInfo->m_pPostEffect = pPostEffectSet;
		pInfo->m_bBeforePostDebugDraw = bBeforePostDebugDraw;
		pInfo->m_bDrawDebugInfo = bDrawDebugInfo;
		pInfo->m_ViewFamilyName = ViewFamilyName;
		pInfo->m_pViewFamily = pViewFamily;
		pCameraActor->m_ViewFamliyInfoArray.AddElement(pInfo);
		pInfo->GetScene();
	}
}